package cn.whale.task.service.impl;

import cn.whale.task.domain.MqLog;
import cn.whale.task.mapper.MqLogMapper;
import cn.whale.task.mq.fallback.MsgConfirmCallback;
import cn.whale.task.service.IMqLogService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale.chen
 * @since 2020-12-14
 */
@Service
@Slf4j
public class MqLogServiceImpl extends ServiceImpl<MqLogMapper, MqLog> implements IMqLogService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MsgConfirmCallback msgConfirmCallback;

    @Override
    public MqLog selectByMesssageId(String messageId) {
        return baseMapper.selectByMesssageId(messageId);

    }

    @Override
    public boolean updateStatus(Integer status, String messageId) {
        return baseMapper.updateStatus(status,messageId) > 0;
    }

    @Override
    public void payResultToMQRetry() {
        //查询发送失败的消息，重试超过 2 次的就不查询了
        List<MqLog> mqLogs =  baseMapper.selectListByStatus(MqLog.STATUS_ERROR,2,10);

        mqLogs.forEach(mqLog -> {
            //重发消息，改成成功状态，如果失败了会被confirmCallback改成error状态
            mqLog.setStatus(mqLog.STATUS_SUCCESS);
            mqLog.setRetry(mqLog.getRetry()+1);
            baseMapper.updateById(mqLog);
            log.info("1.定时重发消息{},exchange={},routingkey={}",mqLog,mqLog.getExchange(),mqLog.getRoutingkey());
            rabbitTemplate.setConfirmCallback(msgConfirmCallback);
            rabbitTemplate.setReturnCallback(msgConfirmCallback);
            rabbitTemplate.setMandatory(true);

            rabbitTemplate.convertAndSend(mqLog.getExchange(),mqLog.getRoutingkey(), JSON.parseObject(mqLog.getContent(),MqLog.class),
                    new CorrelationData(mqLog.getMessageId()));
            log.info("MQ消息重试{}",mqLog);
        });
    }
}
